/**
 * @Author: Boring
 * @Description:
 * @File:  client-go
 * @Date: 2024-02-24 17:09
 */

package main

import (
	"context"
	"fmt"
	appsv1 "k8s.io/api/apps/v1"
	corv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/json"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"oam-manage-backend/utils/logs"
)

func main() {
	// 1.初始化config实例
	config, err := clientcmd.BuildConfigFromFlags("", "./config/meta.kubeconfig")
	if err != nil {
		panic(err.Error())
	}
	// 2.创建客户端工具 clientset
	clients, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}
	//3.操作集群
	// kubectl get api-resources 查看资源对应的API
	pods, err := clients.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		logs.Error(nil, "查询pod列表失败")
	} else {
		fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
	}

	// 查询deployment列表
	deployments, err := clients.AppsV1().Deployments("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		logs.Error(nil, "查询deployment列表失败")
	} else {
		deploymentItems := deployments.Items
		for _, deploy := range deploymentItems {
			fmt.Printf("当前资源的名字是: %s, namespace: %s \n", deploy.Name, deploy.Namespace)
		}
	}
	// get 方法
	podDetail, err := clients.CoreV1().Pods("kube-system").Get(context.TODO(), "etcd-k8s-master", metav1.GetOptions{})
	if err != nil {
		fmt.Println("查询详情失败")
	} else {
		fmt.Println("查询到详情", podDetail)
		fmt.Println("第一个容器的镜像是:", podDetail.Spec.Containers[0].Name)
	}
	// 命名空间详情
	namespaceDetail, err := clients.CoreV1().Namespaces().Get(context.TODO(), "kube-system", metav1.GetOptions{})
	if err != nil {
		fmt.Println("查询详情失败")
	} else {
		fmt.Println("查询到详情", namespaceDetail)
	}

	//更新操作
	// 获取deployment 并修改
	//deployDetail, _ := clients.AppsV1().Deployments("default").Get(context.TODO(), "nginx-deployment", metav1.GetOptions{})
	//fmt.Println("查询到deployment，名字是：", deployDetail.Name)
	//// 获取当前的label
	//labels := deployDetail.Labels
	//
	//labels["app"] = "newlabelvalue"
	//fmt.Println(labels)

	//deployDetail.Annotations['new-anno'] = "newlabels"
	//_, err = clients.AppsV1().Deployments("default").Update(context.TODO(), deployDetail, metav1.UpdateOptions{})
	//if err != nil {
	//	fmt.Println("更新失败:", err.Error())
	//}

	//创建一个deployment
	var newNamespce corv1.Namespace
	newNamespce.Name = "test1"
	_, err = clients.CoreV1().Namespaces().Create(context.TODO(), &newNamespce, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("创建namespace失败", err.Error())
	}

	//创建一个deployment
	var newDeployment appsv1.Deployment
	newDeployment.Name = "nginx"
	newDeployment.Namespace = "test1"
	label := make(map[string]string)
	label["app"] = "nginx"
	label["version"] = "v1"

	// 此处更改的是deployment的label
	newDeployment.Labels = label
	// 此处更改的是selector下面的参数
	newDeployment.Spec.Selector = &metav1.LabelSelector{}
	newDeployment.Spec.Selector.MatchLabels = label
	// 此处更改的是pod的label
	newDeployment.Spec.Template.Labels = label
	// 创建容器
	var containers []corv1.Container
	// 先声明一个容器
	var container corv1.Container
	container.Image = "redis"
	container.Name = "redis"
	containers = append(containers, container)
	container.Image = "nginx"
	container.Name = "nginx"
	containers = append(containers, container)
	newDeployment.Spec.Template.Spec.Containers = containers
	_, err = clients.AppsV1().Deployments("test1").Create(context.TODO(), &newDeployment, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("创建deployment失败", err.Error())
	}

	//通过json串创建k8s资源
	deployJson := `
    {
    "kind": "Deployment",
    "apiVersion": "apps/v1",
    "metadata": {
        "name": "redis",
        "creationTimestamp": null,
        "labels": {
            "app": "redis"
        }
    },
    "spec": {
        "replicas": 1,
        "selector": {
            "matchLabels": {
                "app": "redis"
            }
        },
        "template": {
            "metadata": {
                "creationTimestamp": null,
                "labels": {
                    "app": "redis"
                }
            },
            "spec": {
                "containers": [
                    {
                        "name": "redis",
                        "image": "redis",
                        "resources": {}
                    }
                ]
            }
        },
        "strategy": {}
    },
    "status": {}
}`
	var newDeployment2 appsv1.Deployment
	// 把json串转为struct
	err = json.Unmarshal([]byte(deployJson), &newDeployment2)
	if err != nil {
		fmt.Println("json转struct失败", err.Error())
	}
	fmt.Println("json转struct之后的deployment配置详情,", newDeployment2)
	_, err = clients.AppsV1().Deployments("default").Create(context.TODO(), &newDeployment2, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("创建deployment失败", err.Error())
	}
}
